package com.sweet.mealon.face.daily.lock.ticket;


import org.junit.Test;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author: crazier.huang
 * @project: faceDaily
 * @date: 2021/4/29 星期四
 * @desc: 排队自旋锁，公平锁
 * ticket锁也是自旋锁的一种，只是它是一种能保证顺序的自选锁，是公平锁
 */
public class TicketSpinLock {
    /**
     * 当期线程能占用的锁的序号
     */
    private AtomicInteger ticketNum = new AtomicInteger(0);

    /**
     * 锁的序号
     */
    private AtomicInteger owner = new AtomicInteger(0);

    private static final  ThreadLocal<Integer> myTicketLocal = new ThreadLocal<Integer>();


    public void lock(){
        //票据
        int myTicket = ticketNum.getAndIncrement();
        myTicketLocal.set(myTicket);
        int count = 0;
        while (myTicket != owner.get()){
            count++;
        }
        System.out.println(String.format("lock times - %s",count));

    }


    public void unlock(){
        int myTicket = myTicketLocal.get();
        owner.compareAndSet(myTicket,myTicket+1);
    }

    @Test
    public void testAdd() throws InterruptedException {
        TicketSpinLock ticketSpinLock = new TicketSpinLock();
        TicketAdd ta = new TicketAdd(ticketSpinLock);
        for (int i = 0; i < 100; i++) {
            Thread t = new Thread(new TicketAddThread(ta));
            t.start();
        }
        TimeUnit.SECONDS.sleep(20);
    }
}
